#pragma once

#include "api/peer_connection_interface.h"
#include "rtc_base/thread.h"
#include <future>
#include <functional>
#include <string>

namespace p2pms
{

//==================================================================================================
// 一个封装了 webrtc::PeerConnection 的 Wrapper 类，将其核心的异步回调操作转换为 std::future<T> 的
// 同步风格接口。
//==================================================================================================
class PeerConnectionWrapper : public webrtc::PeerConnectionObserver
{
public:
	struct IPeerConnectionHandler
	{
	public:
		virtual ~IPeerConnectionHandler() = default;

		virtual void OnSignalingChange(
			webrtc::PeerConnectionInterface::SignalingState new_state) = 0;
		virtual void OnIceConnectionChange(
			webrtc::PeerConnectionInterface::IceConnectionState new_state) = 0;
		virtual void OnIceGatheringChange(
			webrtc::PeerConnectionInterface::IceGatheringState new_state) = 0;
		virtual void OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
			const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& streams) = 0;
		virtual void OnRemoveTrack(
			rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) = 0;
		virtual void OnIceCandidate(
			const webrtc::IceCandidateInterface* candidate) = 0;
		virtual void OnRenegotiationNeeded() = 0;
	};

	PeerConnectionWrapper(rtc::Thread* sdk_thread, std::shared_ptr<IPeerConnectionHandler> handler);
	~PeerConnectionWrapper();

	bool Init(webrtc::PeerConnectionFactoryInterface* pc_factory);
	void Destroy();

	// 将异步操作转换为返回 future 的同步风格接口
	std::future<std::string> CreateOffer();
	std::future<std::string> CreateAnswer();
	std::future<void> SetRemoteDescription(webrtc::SessionDescriptionInterface* desc);
	
	// AddIceCandidate 是异步的，但通常不需要等待其完成，所以保持 void 返回值
	void AddIceCandidate(std::unique_ptr<webrtc::IceCandidateInterface> candidate);
	webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> AddTransceiver(
		cricket::MediaType media_type, const webrtc::RtpTransceiverInit& init);

	webrtc::PeerConnectionInterface* pc() const { return m_pc.get(); }

private:
	// PeerConnectionObserver 的实现
	void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override;
	void OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> channel) override {}
	void OnRenegotiationNeeded() override;
	void OnIceConnectionChange(
		webrtc::PeerConnectionInterface::IceConnectionState new_state) override;
	void OnIceGatheringChange(
		webrtc::PeerConnectionInterface::IceGatheringState new_state) override;
	void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
	void OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver, 
		const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& streams) override;
	void OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) override;

private:
	class CreateSessionDescriptionObserver : public webrtc::CreateSessionDescriptionObserver
	{
	public:
		CreateSessionDescriptionObserver(rtc::scoped_refptr<webrtc::PeerConnectionInterface> pc);

		std::future<std::string> GetCreateFuture();

		// CreateSessionDescriptionObserver
		void OnSuccess(webrtc::SessionDescriptionInterface* desc) override;
		void OnFailure(webrtc::RTCError error) override;

	private:
		std::promise<std::string> m_create_promise;
		rtc::scoped_refptr<webrtc::PeerConnectionInterface> m_pc;
		std::string m_sdp;
	};

	class SetSessionDescriptionObserver : public webrtc::SetSessionDescriptionObserver
	{
	public:
		std::future<void> GetSetFuture();

		// SetSessionDescriptionObserver
		void OnSuccess() override;
		void OnFailure(webrtc::RTCError error) override;

	private:
		std::promise<void> m_set_promise;
	};

	rtc::scoped_refptr<webrtc::PeerConnectionInterface> m_pc;
	rtc::Thread* m_sdk_thread;
	std::weak_ptr<IPeerConnectionHandler> m_handler;
};

} // namespace p2pms